#include <iostream>
#include<assert.h>
#include<typeinfo>
#include<any>


class Any
{
private:
    class holder
    {
    public:
        holder()
        {
        }

        virtual ~holder()
        {
        }

        virtual const std::type_info& type() = 0;

        virtual holder *clone() = 0;
    };
    template <class T>
    class place_holder : public holder
    {
    public:
        place_holder(const T& val):_val(val)
        {}
        const std::type_info& type()
        {
            return typeid(T);
        }

        holder *clone()
        {
            return new place_holder(_val);
        }

    public:
        T _val;
    };

    holder *_content;

public:
    Any() : _content(nullptr)
    {
    }

    template <class T>
    Any(const T &val)
        : _content(new place_holder<T>(val))
    {
    }

    Any &swap(Any &other)
    {
        std::swap(_content, other._content);
        return *this;
    }

    Any(const Any &other) : _content(other._content ? other._content->clone() : nullptr)
    {
    }
    template <class T>
    Any &operator=(const T &val)
    {
        Any(val).swap(*this);
        return *this;
    }

    Any &operator=(const Any &other)
    {
        Any(other).swap(*this);
        return *this;
    }

    template <class T>
    T *get()
    {
        assert(typeid(T) == _content->type());
        return &(((place_holder<T> *)_content)->_val);
    }

    ~Any()
    {
        delete _content;
        _content = nullptr;
    }
};

// int main()
// {
//     Any _a = 10;
//     int * pa = _a.get<int>();
//     std::cout << *pa << std::endl;
//     return 0;
// }


//c++17中any的使用 (any_cast接口的使用)

// int main()
// {
//     std::any _a = 10;
//     int* pa = std::any_cast<int>(&_a);
//     std::cout << *pa << std::endl;
//     return 0;
// }

